const WebSocket = require('ws');
const http = require('http');
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const config = require('./config/baidu');

class VoiceTranslation {
  constructor() {
    this.webClients = new Set();
    this.accessToken = null;
    this.tokenExpiry = null;
    this.realtimeASRSessions = new Map(); // 存储实时ASR会话
  }

  async start() {
    console.log('启动语音识别系统...');

    // 创建HTTP服务器
    this.createHttpServer();

    // 创建WebSocket服务器
    this.createWebSocketServer();

    // 获取百度API访问令牌
    await this.getAccessToken();

    console.log('系统已启动');
    console.log('WebSocket服务器运行在: ws://localhost:8080');
    console.log('HTTP服务器运行在: http://localhost:3000');
    console.log('按 Ctrl+C 退出');

    // 测试翻译功能
    this.testTranslation();

    // 测试多语言翻译功能
    setTimeout(() => {
      this.testMultiLanguageTranslation();
    }, 3000);

    // 处理退出信号
    process.on('SIGINT', () => {
      this.stop();
    });
  }

  createHttpServer() {
    this.httpServer = http.createServer((req, res) => {
      // 添加CORS头
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
      res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

      // 测试API端点
      if (req.url === '/api/test') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ status: 'ok', message: 'API正常工作' }));
        return;
      }

      // 环境变量检查端点
      if (req.url === '/api/env-check') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        const configured = !!(process.env.BAIDU_APP_ID && process.env.BAIDU_API_KEY && process.env.BAIDU_SECRET_KEY);
        res.end(JSON.stringify({ configured, message: configured ? '环境变量已配置' : '环境变量未配置' }));
        return;
      }

      if (req.url === '/' || req.url === '/index.html') {
        const htmlPath = path.join(__dirname, 'test.html');
        if (fs.existsSync(htmlPath)) {
          const html = fs.readFileSync(htmlPath, 'utf8');
          res.writeHead(200, { 'Content-Type': 'text/html' });
          res.end(html);
        } else {
          res.writeHead(404);
          res.end('test.html not found');
        }
      } else if (req.url === '/interpreter' || req.url === '/interpreter.html') {
        const htmlPath = path.join(__dirname, 'interpreter.html');
        if (fs.existsSync(htmlPath)) {
          const html = fs.readFileSync(htmlPath, 'utf8');
          res.writeHead(200, { 'Content-Type': 'text/html' });
          res.end(html);
        } else {
          res.writeHead(404);
          res.end('interpreter.html not found');
        }
      } else {
        res.writeHead(404);
        res.end('Not found');
      }
    });

    this.httpServer.listen(3000, () => {
      console.log('HTTP服务器启动在端口 3000');
      console.log('WebSocket服务器也运行在端口 3000（共享端口）');
      console.log('访问 http://localhost:3000 - 语音识别测试');
      console.log('访问 http://localhost:3000/interpreter - 语音同传系统');
    });
  }

  createWebSocketServer() {
    // 使用HTTP服务器来创建WebSocket服务器，共享同一个端口
    this.wss = new WebSocket.Server({ server: this.httpServer });

    this.wss.on('connection', (ws) => {
      console.log('新的Web客户端连接');
      this.webClients.add(ws);

      ws.on('message', (message) => {
        try {
          const data = JSON.parse(message);
          this.handleWebClientMessage(data, ws);
        } catch (error) {
          console.error('解析Web客户端消息失败:', error);
        }
      });

      ws.on('close', () => {
        console.log('Web客户端断开连接');
        this.webClients.delete(ws);
      });

      ws.on('error', (error) => {
        console.error('Web客户端连接错误:', error);
        this.webClients.delete(ws);
      });
    });
  }

  async getAccessToken() {
    if (this.accessToken && this.tokenExpiry > Date.now()) {
      return this.accessToken;
    }

    try {
      const response = await axios.post(
        'https://aip.baidubce.com/oauth/2.0/token',
        null,
        {
          params: {
            grant_type: 'client_credentials',
            client_id: config.API_KEY,
            client_secret: config.SECRET_KEY
          }
        }
      );

      this.accessToken = response.data.access_token;
      this.tokenExpiry = Date.now() + (response.data.expires_in * 1000);
      console.log('百度API访问令牌获取成功');

      return this.accessToken;
    } catch (error) {
      console.error('获取访问令牌失败:', error.message);
      throw error;
    }
  }

  // 实时语音识别和翻译
  async startRealtimeASR(fromLang = 'zh', toLangs = ['en']) {
    return new Promise((resolve, reject) => {
      const sessionId = uuidv4();
      console.log('开始实时语音识别会话:', sessionId);

      // 创建WebSocket连接到百度实时语音识别API
      const wsUrl = `wss://vop.baidu.com/realtime_asr?sn=${sessionId}`;
      const baiduWs = new WebSocket(wsUrl);



      baiduWs.on('open', async () => {
        console.log('百度实时语音识别连接已建立');

        try {
          // 发送开始参数帧
          const startFrame = {
            type: 'START',
            data: {
              appid: parseInt(config.APP_ID),
              appkey: config.API_KEY,
              dev_pid: 15372, // 中文普通话加强标点
              cuid: 'web_client_' + sessionId,
              format: 'pcm',
              sample: 16000
            }
          };

          baiduWs.send(JSON.stringify(startFrame));
          console.log('发送开始参数帧');

          resolve({
            sessionId,
            sendAudio: (audioData) => this.sendAudioToBaidu(baiduWs, audioData),
            close: () => this.closeBaiduASR(baiduWs),
            baiduWs: baiduWs
          });

        } catch (error) {
          console.error('发送开始帧失败:', error);
          reject(error);
        }
      });

      baiduWs.on('message', async (data) => {
        try {
          const result = JSON.parse(data.toString());
          console.log('收到百度ASR结果:', result);

          if (result.type === 'FIN_TEXT' && result.err_no === 0 && result.result) {
            // 最终识别结果，进行翻译
            const originalText = result.result;
            console.log('识别完成:', originalText);

            if (originalText.trim()) {
              const translations = await this.translateToMultipleLanguages(originalText, fromLang, toLangs);

              // 广播翻译结果到所有Web客户端
              this.broadcastToClients({
                type: 'translation',
                data: {
                  original: originalText,
                  translations: translations,
                  fromLang: fromLang,
                  toLangs: toLangs,
                  timestamp: new Date().toISOString()
                }
              });
            }
          } else if (result.type === 'MID_TEXT' && result.result) {
            // 临时识别结果
            console.log('临时识别结果:', result.result);
          }

        } catch (error) {
          console.error('处理百度ASR消息失败:', error);
        }
      });

      baiduWs.on('error', (error) => {
        console.error('百度实时语音识别错误:', error);
        reject(error);
      });

      baiduWs.on('close', () => {
        console.log('百度实时语音识别连接已关闭');
      });
    });
  }

  sendAudioToBaidu(baiduWs, audioData) {
    if (baiduWs.readyState === WebSocket.OPEN) {
      // 发送二进制音频数据帧
      baiduWs.send(audioData);
    }
  }

  closeBaiduASR(baiduWs) {
    if (baiduWs.readyState === WebSocket.OPEN) {
      // 发送结束帧
      const finishFrame = { type: 'FINISH' };
      baiduWs.send(JSON.stringify(finishFrame));
      console.log('发送结束帧');

      setTimeout(() => {
        baiduWs.close();
      }, 1000);
    }
  }

  async translateToMultipleLanguages(originalText, fromLang, toLangs) {
    const translations = {};

    // 并行翻译到所有目标语言
    const translationPromises = toLangs.map(async (toLang) => {
      const translatedText = await this.translateText(originalText, fromLang, toLang);
      return { toLang, translatedText };
    });

    const results = await Promise.all(translationPromises);

    // 构建翻译结果对象
    results.forEach(({ toLang, translatedText }) => {
      translations[toLang] = translatedText;
    });

    return translations;
  }

  async translateText(text, from, to) {
    try {
      console.log('开始百度智能云翻译:', text, '从', from, '到', to);

      // 直接使用百度智能云翻译API
      const baiduResult = await this.tryBaiduTranslate(text, from, to);
      if (baiduResult) {
        return baiduResult;
      }

      // 如果翻译失败，使用本地翻译作为备用
      console.log('百度智能云翻译失败，使用本地翻译逻辑');
      return this.localTranslate(text, from, to);

    } catch (error) {
      console.error('翻译过程出错:', error.message);
      return this.localTranslate(text, from, to);
    }
  }

  async tryBaiduTranslate(text, from, to) {
    try {
      console.log('调用百度智能云文本翻译API');

      // 获取访问令牌
      const token = await this.getAccessToken();

      // 调用百度智能云文本翻译API
      const response = await axios.post(
        `https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=${token}`,
        {
          q: text.trim(),
          from: from,
          to: to
        },
        {
          headers: {
            'Content-Type': 'application/json'
          },
          timeout: 10000
        }
      );

      console.log('百度智能云翻译API响应:', response.data);

      if (response.data.error_code) {
        console.error('百度翻译API错误:', response.data.error_code, response.data.error_msg);
        return null;
      }

      if (response.data.result && response.data.result.trans_result && response.data.result.trans_result.length > 0) {
        const translatedText = response.data.result.trans_result[0].dst;
        console.log('百度智能云翻译成功:', text, '->', translatedText);
        return translatedText;
      }

      return null;

    } catch (error) {
      console.error('百度智能云翻译请求失败:', error.message);
      if (error.response) {
        console.error('响应状态:', error.response.status);
        console.error('响应数据:', error.response.data);
      }
      return null;
    }
  }

  localTranslate(text, from, to) {
    // 改进的本地翻译逻辑
    console.log('使用本地翻译:', text, '从', from, '到', to);

    // 常用词汇翻译字典
    const dictionary = {
      'zh-en': {
        '你好': 'Hello', '世界': 'World', '测试': 'Test', '语音': 'Voice',
        '识别': 'Recognition', '翻译': 'Translation', '系统': 'System',
        '欢迎': 'Welcome', '谢谢': 'Thank you', '再见': 'Goodbye',
        '会议': 'Meeting', '开始': 'Start', '结束': 'End', '时间': 'Time',
        '今天': 'Today', '明天': 'Tomorrow', '昨天': 'Yesterday',
        '请': 'Please', '是的': 'Yes', '不是': 'No', '可以': 'Can',
        '好的': 'OK', '没问题': 'No problem', '抱歉': 'Sorry',
        '工作': 'Work', '学习': 'Study', '生活': 'Life', '朋友': 'Friend'
      },
      'en-zh': {
        'hello': '你好', 'world': '世界', 'test': '测试', 'voice': '语音',
        'recognition': '识别', 'translation': '翻译', 'system': '系统',
        'welcome': '欢迎', 'thank you': '谢谢', 'goodbye': '再见',
        'meeting': '会议', 'start': '开始', 'end': '结束', 'time': '时间',
        'today': '今天', 'tomorrow': '明天', 'yesterday': '昨天',
        'please': '请', 'yes': '是的', 'no': '不是', 'can': '可以',
        'ok': '好的', 'no problem': '没问题', 'sorry': '抱歉',
        'work': '工作', 'study': '学习', 'life': '生活', 'friend': '朋友'
      }
    };

    const translationKey = `${from}-${to}`;
    const dict = dictionary[translationKey];

    if (dict) {
      // 尝试词汇匹配翻译
      let result = text;
      for (const [original, translated] of Object.entries(dict)) {
        const regex = new RegExp(original, 'gi');
        result = result.replace(regex, translated);
      }

      if (result !== text) {
        console.log('词汇翻译成功:', text, '->', result);
        return result;
      }
    }

    // 如果没有匹配的词汇，返回带语言标识的原文
    const langNames = {
      'zh': '中文', 'en': 'English', 'jp': '日本語', 'kor': '한국어',
      'fra': 'Français', 'de': 'Deutsch', 'spa': 'Español', 'ru': 'Русский'
    };

    const result = `[${langNames[to] || to.toUpperCase()}] ${text}`;
    console.log('使用标识翻译:', text, '->', result);
    return result;
  }



  handleWebClientMessage(data, ws) {
    switch (data.type) {
      case 'start':
        // 开始实时语音识别
        const fromLang = data.fromLang || 'zh';
        const toLangs = data.toLangs || ['en'];

        console.log('开始实时语音识别会话，翻译配置:', fromLang, '->', toLangs.join(', '));

        this.startRealtimeASR(fromLang, toLangs).then(session => {
          // 存储会话信息
          this.realtimeASRSessions.set(ws, session);
          console.log('实时ASR会话已建立:', session.sessionId);

          // 通知客户端会话已建立
          ws.send(JSON.stringify({
            type: 'session_started',
            sessionId: session.sessionId
          }));

        }).catch(error => {
          console.error('启动实时ASR失败:', error);
          ws.send(JSON.stringify({
            type: 'error',
            message: '启动实时语音识别失败'
          }));
        });
        break;

      case 'audio':
        // 发送音频数据到实时语音识别
        if (data.audioData) {
          const audioBuffer = Buffer.from(data.audioData, 'base64');
          const session = this.realtimeASRSessions.get(ws);

          if (session) {
            session.sendAudio(audioBuffer);
          } else {
            console.log('没有找到对应的ASR会话，忽略音频数据');
          }
        }
        break;

      case 'stop':
        // 停止实时语音识别
        const session = this.realtimeASRSessions.get(ws);
        if (session) {
          session.close();
          this.realtimeASRSessions.delete(ws);
          console.log('实时ASR会话已关闭:', session.sessionId);
        }
        break;
      case 'start':
        console.log('Web客户端开始录音');
        break;
      case 'stop':
        console.log('Web客户端停止录音');
        break;
      case 'setLanguage':
        console.log('设置翻译语言:', data.fromLang, '->', data.toLang);
        break;
      default:
        console.log('未知的Web客户端消息类型:', data.type);
    }
  }



  broadcastToClients(message) {
    this.webClients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify(message));
      }
    });
  }

  async testTranslation() {
    console.log('\n=== 测试百度智能云多语言翻译API ===');
    try {
      const testResult1 = await this.translateText('你好世界', 'zh', 'en');
      console.log('中文->英语:', testResult1);

      const testResult2 = await this.translateText('你好世界', 'zh', 'jp');
      console.log('中文->日语:', testResult2);

      const testResult3 = await this.translateText('你好世界', 'zh', 'fra');
      console.log('中文->法语:', testResult3);

      console.log('=== 多语言翻译API测试完成 ===\n');
    } catch (error) {
      console.error('翻译测试失败:', error.message);
    }
  }

  async testMultiLanguageTranslation() {
    console.log('\n=== 测试多语言并行翻译功能 ===');
    try {
      // 模拟多语言翻译请求
      const toLangs = ['en', 'jp', 'fra'];
      const originalText = '欢迎使用多语言同传系统';

      console.log('原文:', originalText);
      console.log('目标语言:', toLangs.join(', '));

      // 并行翻译到所有目标语言
      const translations = {};
      const translationPromises = toLangs.map(async (toLang) => {
        const translatedText = await this.translateText(originalText, 'zh', toLang);
        return { toLang, translatedText };
      });

      const results = await Promise.all(translationPromises);

      // 构建翻译结果对象
      results.forEach(({ toLang, translatedText }) => {
        translations[toLang] = translatedText;
      });

      console.log('多语言翻译结果:');
      for (const [lang, text] of Object.entries(translations)) {
        console.log(`  ${lang}: ${text}`);
      }

      console.log('=== 多语言并行翻译测试完成 ===\n');
    } catch (error) {
      console.error('多语言翻译测试失败:', error.message);
    }
  }

  stop() {
    console.log('\n正在关闭系统...');
    if (this.wss) {
      this.wss.close();
    }
    process.exit(0);
  }
}

// 启动应用
const app = new VoiceTranslation();
app.start().catch(console.error);